package com.wondedDream.jwt;

import com.wondedDream.jwt.annotation.JwtTokenRequired;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@EnableWebSecurity
public class JwtAuthFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthFilter.class);
    private final MyUserDetailsService userDetailsService;
    private final RequestMappingHandlerMapping handlerMapping;

    private static final String SECRET_KEY = "your-secret-key"; // 替换为你的密钥
    private static final String HEADER_STRING = "Authorization";
    private static final String TOKEN_PREFIX = "Bearer ";

    public JwtAuthFilter(MyUserDetailsService userDetailsService, RequestMappingHandlerMapping handlerMapping) {
        this.userDetailsService = userDetailsService;
        this.handlerMapping = handlerMapping;
    }


    @SneakyThrows
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {

        HandlerExecutionChain handler = handlerMapping.getHandler(request);
        if (handler != null) {
            Object handlerObject = handler.getHandler();
            HandlerMethod handlerMethod = (HandlerMethod) handlerObject;
            // 检查类级别和方法级别的@JwtTokenRequired注解
            if (hasJwtTokenRequiredAnnotation(handlerMethod)) {
                // 获取请求头中的token
                String openId = null;
                String jwtToken = null;
                String authToken = extractTokenFromRequest(request);
                if (authToken != null && !authToken.isEmpty()) {

                    jwtToken = authToken;
                    Claims claims = Jwts.parser()
                            .setSigningKey(SECRET_KEY)
                            .parseClaimsJws(jwtToken)
                            .getBody();
                    openId = claims.getSubject();
                }
                if (openId != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                    UserDetails userDetails = this.userDetailsService
                            .loadUserByUsername(openId);

                    // 创建认证对象并设置到SecurityContext中
                    if (userDetails != null) {
                        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                                new UsernamePasswordAuthenticationToken(
                                        userDetails, null, userDetails.getAuthorities());
                        usernamePasswordAuthenticationToken
                                .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                    }else{
                        // 处理无效token的情况，例如返回401 Unauthorized
                        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid JWT token");
                        return;
                    }
                }
            }

            chain.doFilter(request, response);
        }
    }

    private boolean hasJwtTokenRequiredAnnotation(HandlerMethod handlerMethod) {
        // 检查方法级别的@JwtTokenRequired注解
        if (handlerMethod.getMethodAnnotation(JwtTokenRequired.class) != null) {
            return true;
        }

        // 检查类级别的@JwtTokenRequired注解
        if (handlerMethod.getBeanType().getAnnotation(JwtTokenRequired.class) != null) {
            return true;
        }

        return false;
    }

    private String extractTokenFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
}
